﻿using System;
using System.Collections.Generic;
using UnityEngine;

public class Triangulator
{
    private List<Vector2> m_points = new List<Vector2>();

    public Triangulator(Vector2[] points)
    {
        this.m_points = new List<Vector2>(points);
    }

    private float Area()
    {
        int count = this.m_points.Count;
        float num2 = 0f;
        int num3 = count - 1;
        int num4 = 0;
        while (num4 < count)
        {
            Vector2 vector = this.m_points[num3];
            Vector2 vector2 = this.m_points[num4];
            num2 += (vector.x * vector2.y) - (vector2.x * vector.y);
            num3 = num4++;
        }
        return (num2 * 0.5f);
    }

    private bool InsideTriangle(Vector2 A, Vector2 B, Vector2 C, Vector2 P)
    {
        float num = C.x - B.x;
        float num2 = C.y - B.y;
        float num3 = A.x - C.x;
        float num4 = A.y - C.y;
        float num5 = B.x - A.x;
        float num6 = B.y - A.y;
        float num7 = P.x - A.x;
        float num8 = P.y - A.y;
        float num9 = P.x - B.x;
        float num10 = P.y - B.y;
        float num11 = P.x - C.x;
        float num12 = P.y - C.y;
        float num15 = (num * num10) - (num2 * num9);
        float num13 = (num5 * num8) - (num6 * num7);
        float num14 = (num3 * num12) - (num4 * num11);
        return (((num15 >= 0f) && (num14 >= 0f)) && (num13 >= 0f));
    }

    private bool Snip(int u, int v, int w, int n, int[] V)
    {
        Vector2 a = this.m_points[V[u]];
        Vector2 b = this.m_points[V[v]];
        Vector2 c = this.m_points[V[w]];
        if (Mathf.Epsilon > (((b.x - a.x) * (c.y - a.y)) - ((b.y - a.y) * (c.x - a.x))))
        {
            return false;
        }
        for (int i = 0; i < n; i++)
        {
            if (((i != u) && (i != v)) && (i != w))
            {
                Vector2 p = this.m_points[V[i]];
                if (this.InsideTriangle(a, b, c, p))
                {
                    return false;
                }
            }
        }
        return true;
    }

    public int[] Triangulate()
    {
        List<int> list = new List<int>();
        int count = this.m_points.Count;
        if (count >= 3)
        {
            int[] v = new int[count];
            if (this.Area() > 0f)
            {
                for (int i = 0; i < count; i++)
                {
                    v[i] = i;
                }
            }
            else
            {
                for (int j = 0; j < count; j++)
                {
                    v[j] = (count - 1) - j;
                }
            }
            int n = count;
            int num5 = 2 * n;
            int num6 = 0;
            int num7 = n - 1;
            while (n > 2)
            {
                if (num5-- <= 0)
                {
                    return list.ToArray();
                }
                int u = num7;
                if (n <= u)
                {
                    u = 0;
                }
                num7 = u + 1;
                if (n <= num7)
                {
                    num7 = 0;
                }
                int w = num7 + 1;
                if (n <= w)
                {
                    w = 0;
                }
                if (this.Snip(u, num7, w, n, v))
                {
                    int item = v[u];
                    int num11 = v[num7];
                    int num12 = v[w];
                    list.Add(item);
                    list.Add(num11);
                    list.Add(num12);
                    num6++;
                    int index = num7;
                    for (int k = num7 + 1; k < n; k++)
                    {
                        v[index] = v[k];
                        index++;
                    }
                    n--;
                    num5 = 2 * n;
                }
            }
            list.Reverse();
        }
        return list.ToArray();
    }
}

